package com.hm.system.service.mongo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.stereotype.Service;

import com.hm.common.common.CommonUtil;
import com.hm.common.common.EncryptUtil;
import com.hm.common.exception.ErrorCode;
import com.hm.common.exception.ServiceException;
import com.hm.common.model.PageInfo;
import com.hm.email.mongo.domain.def.EmailTypeDef;
import com.hm.email.share.service.SendEmailService;
import com.hm.email.vo.EmailVo;
import com.hm.system.auto.SystemProperties;
import com.hm.system.auto.SystemProperties.SystemInit;
import com.hm.system.mongo.domain.def.SysUserDef;
import com.hm.system.mongo.domain.system.QSysUserInfo;
import com.hm.system.mongo.domain.system.SysUserInfo;
import com.hm.system.mongo.vo.system.SysUserInfoVo;
import com.hm.system.share.repository.mongo.system.SysUserInfoRepository;
import com.hm.system.share.service.mongo.system.SysUserInfoService;
import com.mysema.query.types.expr.BooleanExpression;

/**
 * @author shishun.wang
 * @date 2016年5月12日 下午10:20:15
 * @version 1.0
 * @describe
 */
@Service
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SysUserInfoServiceImpl implements SysUserInfoService {

	@Autowired
	private SysUserInfoRepository sysUserInfoRepository;
	
	@Autowired
	private SystemProperties systemProperties;

	@Autowired
	private SendEmailService sendEmailService;
	
	private static Logger logger = LoggerFactory.getLogger(SysUserInfoServiceImpl.class);

	public String addSysUserInfo(SysUserInfoVo sysUserInfoVo, String operationUser) {
		QSysUserInfo info = QSysUserInfo.sysUserInfo;
		BooleanExpression pageable = info.name.eq(sysUserInfoVo.getName());
		Iterator<SysUserInfo> iterator = sysUserInfoRepository.findAll(pageable).iterator();
		while (iterator.hasNext()) {
			throw ServiceException.warn("该用户名已存在,请重新选择");
		}

		pageable = info.name.eq(sysUserInfoVo.getMobile());
		iterator = sysUserInfoRepository.findAll(pageable).iterator();
		while (iterator.hasNext()) {
			throw ServiceException.warn("该电话号码已存在,请重新选择");
		}

		pageable = info.email.eq(sysUserInfoVo.getEmail());
		iterator = sysUserInfoRepository.findAll(pageable).iterator();
		while (iterator.hasNext()) {
			throw ServiceException.warn("该邮箱已存在,请重新选择");
		}

		String pwd = EncryptUtil.getRandomPwd();

		SysUserInfo sysUserInfo = new SysUserInfo();
		{
			sysUserInfo.setPwd(EncryptUtil.Md5.getMD5Code(pwd));
			sysUserInfo.setName(sysUserInfoVo.getName());
			sysUserInfo.setCreateUser(operationUser);
			sysUserInfo.setAlias(sysUserInfoVo.getAlias());
			sysUserInfo.setMobile(sysUserInfoVo.getMobile());
			sysUserInfo.setEmail(sysUserInfoVo.getEmail());
			sysUserInfo.setUserDef(sysUserInfoVo.getUserDef());
			sysUserInfo.setNote(sysUserInfoVo.getNote());
		}
		String userId = sysUserInfoRepository.save(sysUserInfo).getId();
		
		// 发送邮件通知用户它的密码
		EmailVo emailModel = new EmailVo();
		{
			emailModel.setTheme("注册密码");
			emailModel.setRecipient(Arrays.asList(new String[] { sysUserInfoVo.getEmail() }));
			emailModel.setContent(sysUserInfoVo.getName() + "你的登陆密码是:" + pwd + ",请勿泄露给其他人");
		}
		sendEmailService.send(emailModel, EmailTypeDef.REGISTER, operationUser);

		return userId;
	}

	@Override
	public String updateSysUserInfo(SysUserInfoVo sysUserInfoVo, String operationUser) {
		SysUserInfo sysUserInfo = sysUserInfoRepository.findOne(sysUserInfoVo.getId());

		QSysUserInfo info = QSysUserInfo.sysUserInfo;
		BooleanExpression pageable = info.name.eq(sysUserInfoVo.getName());
		Iterator<SysUserInfo> iterator = sysUserInfoRepository.findAll(pageable).iterator();
		while (iterator.hasNext()) {
			SysUserInfo userInfo = iterator.next();
			if (!userInfo.getId().equals(sysUserInfo.getId())) {
				throw ServiceException.warn("该用户名已存在,请重新选择");
			}
		}

		pageable = info.name.eq(sysUserInfoVo.getMobile());
		iterator = sysUserInfoRepository.findAll(pageable).iterator();
		while (iterator.hasNext()) {
			SysUserInfo userInfo = iterator.next();
			if (!userInfo.getId().equals(sysUserInfo.getId())) {
				throw ServiceException.warn("该电话号码已存在,请重新选择");
			}
		}

		pageable = info.email.eq(sysUserInfoVo.getEmail());
		iterator = sysUserInfoRepository.findAll(pageable).iterator();
		while (iterator.hasNext()) {
			SysUserInfo userInfo = iterator.next();
			if (!userInfo.getId().equals(sysUserInfo.getId())) {
				throw ServiceException.warn("该邮箱已存在,请重新选择");
			}
		}

		sysUserInfo = sysUserInfoRepository.findOne(sysUserInfoVo.getId());
		if (null == sysUserInfo) {
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND, "SysUserInfo：" + sysUserInfoVo.getId());
		} else {
			sysUserInfo.setName(sysUserInfoVo.getName());
			sysUserInfo.setCreateUser(operationUser);
			sysUserInfo.setAlias(sysUserInfoVo.getAlias());
			sysUserInfo.setMobile(sysUserInfoVo.getMobile());
			sysUserInfo.setEmail(sysUserInfoVo.getEmail());
			sysUserInfo.setNote(sysUserInfoVo.getNote());
			sysUserInfo.setUserDef(sysUserInfoVo.getUserDef());
		}
		return sysUserInfoRepository.save(sysUserInfo).getId();
	}

	@Override
	public SysUserInfoVo checkSysUserInfo(String name, String pwd) {
		QSysUserInfo info = QSysUserInfo.sysUserInfo;
		SysUserInfo sysUserInfo = sysUserInfoRepository
				.findOne(info.name.eq(name).and(info.pwd.eq(EncryptUtil.Md5.getMD5Code(pwd))));

		SysUserInfoVo sysUserInfoVo = new SysUserInfoVo();
		if (null != sysUserInfo) {
			sysUserInfoVo.setId(sysUserInfo.getId());
			sysUserInfoVo.setName(sysUserInfo.getName());
			sysUserInfoVo.setMobile(sysUserInfo.getMobile());
			sysUserInfoVo.setAlias(sysUserInfo.getAlias());
			sysUserInfoVo.setCreateTime(sysUserInfo.getCreateTime());
			sysUserInfoVo.setEmail(sysUserInfo.getEmail());
			sysUserInfoVo.setRoleIds(sysUserInfo.getRoleIds());
			sysUserInfoVo.setHeadPortrait(sysUserInfo.getHeadPortrait());
			sysUserInfoVo.setUserDef(sysUserInfo.getUserDef());
			sysUserInfoVo.setNote(sysUserInfoVo.getNote());

			return sysUserInfoVo;
		}
		return null;
	}

	@Override
	public String deleteSysUserInfo(SysUserInfoVo sysUserInfoVo, String operationUser) {
		sysUserInfoRepository.delete(sysUserInfoVo.getId());
		return sysUserInfoVo.getId();
	}

	@Override
	public SysUserInfoVo getSysUserInfo(String id) {
		SysUserInfo sysUserInfo = sysUserInfoRepository.findOne(id);
		if (null == sysUserInfo) {
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND, "SysUserInfo：" + id);
		}

		SysUserInfoVo sysUserInfoVo = new SysUserInfoVo();
		{
			sysUserInfoVo.setId(sysUserInfo.getId());
			sysUserInfoVo.setName(sysUserInfo.getName());
			sysUserInfoVo.setMobile(sysUserInfo.getMobile());
			sysUserInfoVo.setAlias(sysUserInfo.getAlias());
			sysUserInfoVo.setCreateTime(sysUserInfo.getCreateTime());
			sysUserInfoVo.setRoleIds(sysUserInfo.getRoleIds());
			sysUserInfoVo.setEmail(sysUserInfo.getEmail());
			sysUserInfoVo.setHeadPortrait(sysUserInfo.getHeadPortrait());
			sysUserInfoVo.setUserDef(sysUserInfo.getUserDef());
			sysUserInfoVo.setNote(sysUserInfo.getNote());
		}
		return sysUserInfoVo;
	}

	@Override
	public PageInfo<SysUserInfoVo> querySysUserInfo(SysUserDef userDef, String name, String mobile, Long startTime,
			Long endTime, Integer pageNumber, Integer pageSize) {
		PageInfo<SysUserInfoVo> pageInfo = new PageInfo<SysUserInfoVo>(pageNumber, pageSize);

		QSysUserInfo qSysUserInfo = QSysUserInfo.sysUserInfo;
		Pageable pageable = new QPageRequest(pageInfo.getPageNumber(), pageInfo.getPageSize(),
				qSysUserInfo.createTime.desc());

		BooleanExpression predicate = qSysUserInfo.name.ne("admin");

		if (CommonUtil.isNotEmpty(userDef)) {
			predicate = predicate.and(qSysUserInfo.userDef.eq(userDef));
		}
		if (CommonUtil.isNotEmpty(name)) {
			predicate = predicate.and(qSysUserInfo.name.like(name));
		}
		if (CommonUtil.isNotEmpty(mobile)) {
			predicate = predicate.and(qSysUserInfo.mobile.like(mobile));
		}

		List<SysUserInfoVo> sysUserInfoVos = new ArrayList<SysUserInfoVo>();
		Page page = sysUserInfoRepository.findAll(predicate, pageable);
		List<SysUserInfo> content = page.getContent();
		for (SysUserInfo sysUserInfo : content) {
			SysUserInfoVo sysUserInfoVo = new SysUserInfoVo();
			{
				sysUserInfoVo.setId(sysUserInfo.getId());
				sysUserInfoVo.setName(sysUserInfo.getName());
				sysUserInfoVo.setMobile(sysUserInfo.getMobile());
				sysUserInfoVo.setAlias(sysUserInfo.getAlias());
				sysUserInfoVo.setCreateTime(sysUserInfo.getCreateTime());
				sysUserInfoVo.setEmail(sysUserInfo.getEmail());
				sysUserInfoVo.setRoleIds(sysUserInfo.getRoleIds());
				sysUserInfoVo.setHeadPortrait(sysUserInfo.getHeadPortrait());
				sysUserInfoVo.setUserDef(sysUserInfo.getUserDef());
				sysUserInfoVo.setNote(sysUserInfo.getNote());
			}

			sysUserInfoVos.add(sysUserInfoVo);
		}

		return pageInfo.execute(page, sysUserInfoVos);
	}

	@Override
	public void removeAll() {
		sysUserInfoRepository.deleteAll();
	}

	@Override
	public String updatePassword(String userId, String oldPwd, String newPwd) {
		SysUserInfo sysUserInfo = sysUserInfoRepository.findOne(userId);
		if(null == sysUserInfo){
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND,"SysUserInfo:"+userId);
		}
		String encodePwd = EncryptUtil.Md5.getMD5Code(oldPwd);
		if(!sysUserInfo.getPwd().equals(encodePwd)){
			throw ServiceException.warn("旧密码错误");
		}else{
			sysUserInfo.setPwd(EncryptUtil.Md5.getMD5Code(newPwd));
			return sysUserInfoRepository.save(sysUserInfo).getId();
		}
	}

	@Override
	public String updateHeadPortrait(String userId, String url) {
		SysUserInfo sysUserInfo = sysUserInfoRepository.findOne(userId);
		if(null == sysUserInfo){
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND,"SysUserInfo:"+userId);
		}
		sysUserInfo.setHeadPortrait(url);
		return sysUserInfoRepository.save(sysUserInfo).getId();
	}

	@Override
	public String disableUser(String userId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String forgetUserPwd(String name,String email,String mobile) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String registerSysUserInfo(SysUserInfoVo sysUserInfoVo, String operationUser){
		QSysUserInfo info = QSysUserInfo.sysUserInfo;
		BooleanExpression pageable = info.name.eq(sysUserInfoVo.getName());
		Iterator<SysUserInfo> iterator = sysUserInfoRepository.findAll(pageable).iterator();
		while (iterator.hasNext()) {
			throw ServiceException.warn("该用户名已存在,请重新选择");
		}

		pageable = info.name.eq(sysUserInfoVo.getMobile());
		iterator = sysUserInfoRepository.findAll(pageable).iterator();
		while (iterator.hasNext()) {
			throw ServiceException.warn("该电话号码已存在,请重新选择");
		}

		pageable = info.email.eq(sysUserInfoVo.getEmail());
		iterator = sysUserInfoRepository.findAll(pageable).iterator();
		while (iterator.hasNext()) {
			throw ServiceException.warn("该邮箱已存在,请重新选择");
		}

		SysUserInfo sysUserInfo = new SysUserInfo();
		{
			sysUserInfo.setName(sysUserInfoVo.getName());
			sysUserInfo.setPwd(EncryptUtil.Md5.getMD5Code(sysUserInfoVo.getPwd()));
			sysUserInfo.setCreateUser(operationUser);
			sysUserInfo.setAlias(sysUserInfoVo.getAlias());
			sysUserInfo.setMobile(sysUserInfoVo.getMobile());
			sysUserInfo.setEmail(sysUserInfoVo.getEmail());
			sysUserInfo.setUserDef(sysUserInfoVo.getUserDef());
			sysUserInfo.setNote(sysUserInfoVo.getNote());
		}
		return sysUserInfoRepository.save(sysUserInfo).getId();
	}

	@Override
	public String initUserInfo() {
		SystemInit systemInit = systemProperties.getSystemInit();
		if(null == systemInit){
			logger.error("初始化系统用户数据不存在");
			return null;
		}else{
			SysUserInfo sysUserInfo = new SysUserInfo();
			{
				sysUserInfo.setName(systemInit.getName());
				sysUserInfo.setPwd(EncryptUtil.Md5.getMD5Code(systemInit.getPwd()));
				sysUserInfo.setMobile(systemInit.getMobile());
				sysUserInfo.setAlias(systemInit.getAlias());
			}
			return sysUserInfoRepository.save(sysUserInfo).getId();
		}
	}
}
